//给定一个按照升序排列的整数数组 nums，和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 
//
// 如果数组中不存在目标值 target，返回 [-1, -1]。 
//
// 进阶： 
//
// 
// 你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗？ 
// 
//
// 
//
// 示例 1： 
//
// 
//输入：nums = [5,7,7,8,8,10], target = 8
//输出：[3,4] 
//
// 示例 2： 
//
// 
//输入：nums = [5,7,7,8,8,10], target = 6
//输出：[-1,-1] 
//
// 示例 3： 
//
// 
//输入：nums = [], target = 0
//输出：[-1,-1] 
//
// 
//
// 提示： 
//
// 
// 0 <= nums.length <= 10⁵ 
// -10⁹ <= nums[i] <= 10⁹ 
// nums 是一个非递减数组 
// -10⁹ <= target <= 10⁹ 
// 
// Related Topics 数组 二分查找 👍 1281 👎 0

package leetcode.editor.cn;

import java.util.Arrays;

public class _34_FindFirstAndLastPositionOfElementInSortedArray {
    public static void main(String[] args) {
        int[] nums = new int[]{1};
        int target = 0;
        Solution solution = new _34_FindFirstAndLastPositionOfElementInSortedArray().new Solution();
        int[] res = solution.searchRange(nums, target);
        System.out.println(Arrays.toString(res));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        /**
         * 官方解法
         * @param nums
         * @param target
         * @return
         */
        public int[] searchRange(int[] nums, int target) {
            if (nums.length == 0) {
                return new int[] {-1, -1};
            }
            int start = findFirstIndex(nums, target);
            int end = findLastIndex(nums, target);
            if (start == -1) {
                return new int[] {-1, -1};
            }
            return new int[] {start, end};
        }

        private int findLastIndex(int[] nums, int target) {
            int start = 0;
            int end = nums.length-1;
            int mid = start;
            while (start < end) {
                mid = start + (end - start + 1) / 2;
                if (nums[mid] == target) {
                    start = mid;
                } else if (nums[mid] < target) {
                    start = mid + 1;
                } else if (nums[mid] > target) {
                    end = mid - 1;
                }
            }
            return nums[end] == target ? end : -1;
        }

        private int findFirstIndex(int[] nums, int target) {
            int start = 0;
            int end = nums.length-1;
            int mid = start;
            while (start < end) {
                mid = start + (end - start) / 2;
                if (nums[mid] == target) {
                    end = mid;
                } else if (nums[mid] < target) {
                    start = mid + 1;
                } else if (nums[mid] > target) {
                    end = mid - 1;
                }
            }
            return nums[start] == target ? start : -1;
        }

        /**
         * 自己写的二分查找，和官方的有区别
         * @param nums
         * @param target
         * @return
         */
        public int[] searchRange_erfen(int[] nums, int target) {
            int i = 0;
            int j = nums.length - 1;
            int mid = i;

            while (i <= j) {
                mid = i + (j - i) / 2;
                if (nums[mid] == target) {
                    break;
                } else if (nums[mid] < target) {
                    i = mid + 1;
                } else if (nums[mid] > target) {
                    j = mid - 1;
                }
            }

            if (i > j) {
                return new int[] {-1, -1};
            } else {
                int start = mid;
                int end = mid;

                for (int k = mid; k >= 0 && nums[k] == target; k--) {
                    start = k;
                }
                for (int k = mid; k < nums.length && nums[k] == target; k++) {
                    end = k;
                }
                return new int[] {start, end};
            }
        }
        /**
         * 暴力解法
         * @param nums
         * @param target
         * @return
         */
        public int[] searchRange_baoli(int[] nums, int target) {
            int start = -1;
            int end = -1;
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] == target && start == -1) {
                    start = i;
                    end = i;
                } else if (nums[i] == target && start != -1) {
                    end = i;
                }
            }
            return new int[]{start, end};
        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}